#!/bin/bash
version="1.0.0"
#save options from cmdline 
option="$1"

plasma_work_dir=""
plasma_edit_file=""
plasma_bak_file=""
sysproxy_state=""
cfw_status=""
cfw_execute=""
clash_core_service_status=""

function version_message()
{
    echo "system proxy management tool, version ${version}."
}

function prepare_cfw()
{
    cfw_status=$(pidof cfw)
    cfw_execute=$(whereis cfw | awk -F": " '{print $2;}')
    cfw_port=$(sed -nE 's/^mixed-port:\s*([0-9]+).*/\1/p' "$HOME"/.config/clash/config.yaml)
    clash_core_service_status=$(systemctl is-active clash-core-service.service)
}

function proxy_prepare_plasma ()
{
    plasma_work_dir="$HOME/.config"
    plasma_edit_file="$plasma_work_dir/kioslaverc"
    plasma_bak_file=$(printf "%s%s" "$plasma_edit_file" ".bak")

    # file exist check
    if [[ ! -e $plasma_edit_file ]]; then
        echo "'$plasma_edit_file' does not exists."
        exit 1;
    fi

    # backup original file
    if [[ ! -e "$plasma_bak_file" ]];then
        cp $plasma_edit_file $plasma_bak_file  
    fi
}

function get_current_proxy_state ()
{
    # 1 -> system proxy opened;
    # 0 -> system proxy closed;
    sysproxy_state=$(grep "ProxyType=" $plasma_edit_file | grep -o '.$')
}

function do_plasma_proxy_change()
{
    case $1 in 
        "on")
            sed 's/^ProxyType=.*[01]$/ProxyType=1/' $plasma_bak_file > $plasma_edit_file;
            return $?;
            ;;
        "off")
            # turn off system proxy
            sed 's/^ProxyType=.*[01]$/ProxyType=0/' $plasma_bak_file > $plasma_edit_file;
            return $?;
            ;;
    esac
}

function do_gnome_proxy_change()
{
    case $1 in
        on)
            gsettings set org.gnome.system.proxy mode 'manual'
            
            # http proxy
            gsettings set org.gnome.system.proxy.http host 'http://127.0.0.1'
            gsettings set org.gnome.system.proxy.http port "$cfw_port"
            
            # https proxy
            gsettings set org.gnome.system.proxy.https host 'http://127.0.0.1'
            gsettings set org.gnome.system.proxy.https port "$cfw_port"
            
            # socks proxy
            gsettings set org.gnome.system.proxy.socks host 'http://127.0.0.1'
            gsettings set org.gnome.system.proxy.socks port "$cfw_port"
            ;;
        off)
            gsettings set org.gnome.system.proxy mode 'none'
            ;;
    esac

}

function do_cfw_state_change()
{
    case $1 in 
        on)
            if [[ ${clash_core_service_status} != "active" ]];then
                echo "clash core service is not running, starting..."
                systemctl start clash-core-service.service
            fi

            if [[ "${cfw_status}" == "" ]]; then
                echo "clash not running, starting..."    
                echo "$cfw_execute 2> /dev/null &" | sh
                if [[ $? ]]; then
                    echo "done";
                    return 0;
                else 
                    return 1;
                fi 
            else 
                return 0;
            fi
            ;;
        off)
            if [[ ${clash_core_service_status} != "inactive" ]];then
                echo "stopping clash core service..."
                systemctl stop clash-core-service.service
            fi

            if [[ "${cfw_status}" != "" ]]; then
                echo "clash is running, closing...";
                # close cfw
                echo "kill -s 9 ${cfw_status}" | sh;
                if [[ "$?" == 0 ]]; then 
                    echo "done.";
                else 
                    echo "error.";
                    return 1;
                fi
            else
                return 0;
            fi
            ;;
        *)
            echo "unknow cfw operation"; 
            return 1
            ;;
    esac
}

function info()
{
    if [[ $sysproxy_state -eq '1' ]];then
        echo 'proxy status: on'
    else
        echo 'proxy status: off'
    fi

    # other status info 
    echo "clash-core-service status: ${clash_core_service_status}"

    if [[ ${cfw_status} == "" ]];then
        echo "clash-for-windows status: off"
    else
        echo "clash-for-windows status: on"
    fi

    echo "clash core main port: ${cfw_port}"
    echo "clash for windows path: ${cfw_execute}"
    echo "desktop environment: ${XDG_CURRENT_DESKTOP}"
}

# start

prepare_cfw
case "$XDG_CURRENT_DESKTOP" in 
    "GNOME")
        case "$option" in 
            on|off)
                do_gnome_proxy_change "$option"
                do_cfw_state_change "$option"
                ;;
            status)
                echo $(gsettings get org.gnome.system.proxy mode);
                ;;
            *)
                echo "invalid para: $option"
        esac
        ;;
    "KDE")
        proxy_prepare_plasma
        get_current_proxy_state
        # modify & save
        case "$option" in
            on|off) 
                do_plasma_proxy_change "$option"
                do_cfw_state_change "$option"
                ;;
            status)
                version_message 
                info
                ;;
            *) 
                echo "invalid para: $option" 
                ;;
        esac
        ;;
    *)
        echo "Unknow desktop environment.";
        ;;
esac
exit 0
